<script lang="ts" setup>
import { Plus, TopRight } from '@element-plus/icons-vue'
import draggable from 'vuedraggable'
import { ElMessage } from 'element-plus'
import { onBeforeRouteLeave, useRoute } from 'vue-router'
import ConferenceForm from './ConferenceForm.vue'
import useSubConference from './useSubConference'
import { getChineseNumber } from './utils'
import useEditConference from './useEditConference'
import subjectApi from '@/api/modules/subConference'
import personApi from '@/api/modules/person'
import conference from '@/api/modules/conference'

const props = defineProps<{
  pid: string
}>()
const route = useRoute()

// 页面状态，是控制会议还是编辑会议
const pageState = route.name === 'ConferenceControl' ? 'control' : 'edit'

// 会议相关逻辑提取
const {
  conferenceDetail,
  fetchData: fetchConference,
  commitChange: saveConference,
  start: conferenceStart,
  finish: conferenceFinish,
} = useEditConference(Number.parseInt(props.pid))

function onFormChange<T extends 'name' | 'position' | 'dataTimeRange'>(name: T, value: (typeof conferenceDetail)[T]) {
  conferenceDetail[name] = value
}

// 议题相关逻辑提取
const {
  subjectList,
  createSubject,
  removePerson,
  changeTagInputVisible,
  addPerson,
  inputValue,
  subjectModel,
  dialogVisible,
  openDialog,
  updateSubject,
  deleteSubject,
  start,
  finish,
} = useSubConference(Number.parseInt(props.pid))

const activeSubjectId = computed(() => {
  for (let i = 0; i < subjectList.value.length; i++) {
    if (i > 0) {
      if (subjectList.value[i - 1].status === 2 && subjectList.value[i].status !== 2) {
        return subjectList.value[i].id
      }
    }
    else {
      if (subjectList.value[i].status !== 2) {
        return subjectList.value[i].id
      }
    }
  }
  return -1
})

const isAnySubjectRunning = computed(() => {
  return subjectList.value.some(item => item.status === 1)
})

// 数据变更的flag，为true表示用户做了数据的变更，但未保存
// 为false表示未修改或者修改后以保存
let updateFlag = false

/**
 * 监测数据是否变动
 */
function watchUpdate() {
  watch([subjectList, conferenceDetail], () => {
    updateFlag = true
  }, { deep: true })
}

if (pageState === 'edit') {
  // 用户试图离开该页面时，进行保存提醒
  addEventListener('beforeunload', (e) => {
    if (updateFlag === true) {
      e.returnValue = 'there are changes that have not been saved yet'
    }
  })
  onBeforeRouteLeave(() => {
    if (updateFlag === true) {
      if (!confirm('您所做的更改尚未保存，是否确认离开')) {
        return false
      }
    }
    updateFlag = false
    return true
  })
}

/**
 * 保存所有数据
 */
function onSaveAll() {
  const saveSubject = new Promise((resolve, reject) => {
    let finishCount = 0
    /**
     * 判断是否完成所有议题的保存任务
     */
    function successJudge() {
      if (finishCount === subjectList.value.length) {
        resolve(true)
      }
    }
    successJudge()
    subjectList.value.forEach((item) => {
      if (item.id === -1) {
        subjectApi.create({
          name: item.name,
          status: 0,
          meeting: {
            id: Number.parseInt(props.pid),
          },
          personList: item.personList,
        }).then((res) => {
          // 请求成功之后，将id改写成服务器中真实的id
          finishCount++
          successJudge()
          item.id = res.data
        }).catch(() => {
          reject(new Error('可能发生了错误，并未完全保存'))
        })
      }
      else {
        subjectApi.update(item).then(() => {
          finishCount++
          successJudge()
        }).catch(() => {
          reject(new Error('可能发生了错误，并未完全保存'))
        })
      }
    })
  })

  Promise.all([saveConference(), saveSubject]).then(() => {
    ElMessage({
      type: 'success',
      message: '保存成功',
    })
  }).catch(() => {
    ElMessage({
      type: 'error',
      message: '保存失败',
    })
  }).finally(() => {
    updateFlag = false
  })
}

// 向服务器拉取会议以及议题数据
fetchConference().then((res) => {
  // 更新议题数据
  updateSubject(res.subjectList)
}).then(() => {
  // 在拉取到服务器数据之后再监测
  // 主要是想监测用户的更改行为，而不是请求导致的数据变化
  if (pageState === 'edit') {
    watchUpdate()
  }
})

async function createPerson(index: number) {
  let id = await addPerson(index);

  if (id === 0 || pageState === 'edit') {
    return;
  }

  const subject = subjectList.value[index];
  await subjectApi.tempUpdate({
    id: subject.id,
    personList: [{
      id,
    }],
  }).then(
    () => {
      console.log('添加成功');
    }
  )
}

// 排序控制
function resortSubConference() {
  subjectList.value.forEach((item, index) => {
    item.order = index
  })
  const newIds = subjectList.value.map(item => ({
    id: item.id,
  }))
  conference.sort(newIds).then(() => {
    ElMessage({
      type: 'success',
      message: '调整顺序成功',
    })
  }).catch(() => {
    ElMessage({
      type: 'error',
      message: '调整顺序失败',
    })
  })
}

const statusText = ['会议待开始', '会议进行中', '会议已结束']

// 状态标签
function parseStatusContent(status: number) {
  if (status === 0) {
    return '未开始'
  }
  else if (status === 1) {
    return '进行中'
  }
  else {
    return '已结束'
  }
}

function parseStatusType(status: number) {
  if (status === 0) {
    return ''
  }
  else if (status === 1) {
    return 'success'
  }
  else {
    return 'info'
  }
}

// 打开屏幕投放新窗口
const router = useRouter()
function openScreenDisplay() {
  const url = router.resolve({
    name: 'screenDisplay',
    params: {
      id: props.pid,
    },
  })
  window.open(url.href)
}
</script>

<template>
  <div>
    <page-header :title="pageState === 'edit' ? '会议编辑' : statusText[conferenceDetail.status]">
      <template v-if="pageState === 'control'">
        <el-button
          type="warning"
          :icon="TopRight"
          @click="openScreenDisplay()"
        >
          屏幕投放
        </el-button>
        <el-button
          type="success"
          :disabled="conferenceDetail.status === 1"
          @click="conferenceStart(conferenceDetail.id)"
        >
          {{ conferenceDetail.status === 2 ? '重新开始' : '开始会议' }}
        </el-button>
        <el-button
          type="danger"
          :disabled="conferenceDetail.status !== 1"
          @click="conferenceFinish(conferenceDetail.id)"
        >
          结束会议
        </el-button>
      </template>
    </page-header>
    <PageMain>
      <el-divider content-position="left">
        <h2 class="divider-title">
          会议信息{{ pageState === 'edit' ? '编辑' : '' }}
        </h2>
      </el-divider>
      <div class="mt-40">
        <ConferenceForm :value="conferenceDetail" :readonly="pageState === 'control'" @change="onFormChange" />
      </div>

      <el-divider content-position="left">
        <h2 class="divider-title">
          议题与人员
        </h2>
      </el-divider>
      <div class="mt-40">
        <el-button v-if="pageState === 'edit'" type="success" :icon="Plus" @click="openDialog">
          新增议题
        </el-button>
        <div style="margin-top: 30px;">
          <table class="table-striped">
            <thead class="table-head">
              <tr>
                <th width="60" class="drag-handler table-title">
                  排序
                </th>
                <th width="80" class="table-title">
                  序号
                </th>
                <th width="400" class="table-title">
                  议题标题
                </th>
                <th class="table-title">
                  列席人员
                </th>
                <th class="table-title">
                  议题状态
                </th>
                <th class="table-title">
                  操作
                </th>
              </tr>
            </thead>
            <draggable
              v-if="subjectList.length > 0"
              v-model="subjectList"
              tag="tbody"
              handle=".drag-handler"
              item-key="order"
              v-bind="{
                animation: 300,
              }"
              @change="resortSubConference()"
            >
              <template #item="{ element, index }">
                <tr class="table-content-row" :class="[element.id === activeSubjectId ? 'active' : '']">
                  <td class="drag-handler table-content">
                    <svg-icon class="dragger" name="grip-dots" />
                  </td>
                  <td class="table-content">
                    {{ getChineseNumber(index + 1) }}
                  </td>
                  <td class="table-content">
                    <el-input v-model="element.name" placeholder="请填写议题标题" :disabled="pageState === 'control'" />
                  </td>
                  <td class="table-content">
                    <el-space wrap>
                      <el-tag
                        v-for="person in element.personList"
                        :key="person.id"
                        size="large"
                        :closable="pageState === 'edit'"
                        @close="removePerson(element.id, person.id,pageState)"
                      >
                        {{ person.name }}
                      </el-tag>
                      <el-input
                        v-if="element.tagInputVisible"
                        v-model="inputValue"
                        class="tag-input"
                        size="default"
                        @blur="createPerson(index)"
                        @keydown.enter="createPerson(index)"
                      />
                      <el-button v-else class="tag-input" @click="changeTagInputVisible(index, true)">
                        + 添加列席人员
                      </el-button>
                    </el-space>
                  </td>
                  <td class="table-content">
                    <el-tag
                      :type="parseStatusType(element.status)"
                      :disable-transitions="true"
                    >
                      {{ parseStatusContent(element.status) }}
                    </el-tag>
                  </td>
                  <td class="table-content" style="min-width: 160px;">
                    <template v-if="pageState === 'edit'">
                      <el-popconfirm
                        confirm-button-text="确认"
                        cancel-button-text="取消"
                        confirm-button-type="danger"
                        icon-color="#F56C6C"
                        title="是否删除该议题"
                        @confirm="deleteSubject(index, element.id)"
                      >
                        <template #reference>
                          <el-button type="danger" size="small">
                            删除
                          </el-button>
                        </template>
                      </el-popconfirm>
                    </template>
                    <template v-else>
                      <el-button
                        :type="element.status === 2 ? '' : 'primary'"
                        size="small"
                        :disabled="isAnySubjectRunning || element.status === 1"
                        @click="start(index, element.id)"
                      >
                        {{ element.status === 2 ? '重新开始' : '开始' }}
                      </el-button>
                      <el-button
                        type="danger"
                        size="small"
                        :disabled="element.status !== 1"
                        @click="finish(index, element.id)"
                      >
                        结束
                      </el-button>
                    </template>
                  </td>
                </tr>
              </template>
            </draggable>
          </table>
          <div v-if="subjectList.length === 0" class="empty-wrapper">
            <el-empty description="没有任何数据" />
          </div>
        </div>
      </div>
    </PageMain>
    <fixed-action-bar v-if="pageState === 'edit'">
      <el-button type="primary" size="large" @click="onSaveAll">
        保存
      </el-button>
    </fixed-action-bar>

    <el-dialog v-model="dialogVisible" title="新增" width="30%" center>
      <el-form :inline="true" :model="subjectModel">
        <el-form-item label="标题">
          <el-input v-model="subjectModel.title" placeholder="请输入议题标题" clearable />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="createSubject">
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.divider-title {
  font-size: 22px;
  font-weight: 300;
  letter-spacing: 3px;
}

.mt-40 {
  margin-top: 40px;
}

.tag-input {
  width: 130px;
}

.table-striped {
  min-width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  border: 1px solid #eee;
}

.dragger {
  cursor: move;
}

.sortable-ghost {
  visibility: hidden;
}

.table-head {
  background-color: #f0f0f0;
}

.table-title {
  padding: 10px;
  text-align: left;
}

.table-content-row {
  background-color: #fff;

  &.active {
    background-color: #f5f5f5;
  }
}

.table-content {
  padding: 10px;
  text-align: left;
}

.empty-wrapper {
  display: flex;
  justify-content: center;
}
</style>
